package com.ytjj.qmyx.supplychain.service;

import Response.AfterSaleOrderResponse;
import Response.Order;
import Response.OrderResponse;
import com.alibaba.fastjson.JSONObject;
import com.ytjj.qmyx.supplychain.common.constants.RedisConstants;
import com.ytjj.qmyx.supplychain.common.enums.ExpressEnum;
import com.ytjj.qmyx.supplychain.common.enums.JushuitanAfterSaleShopStatusEnum;
import com.ytjj.qmyx.supplychain.common.enums.JushuitanOrderStatusEnum;
import com.ytjj.qmyx.supplychain.common.model.dto.JunshuitanRsponseDto;
import com.ytjj.qmyx.supplychain.mapper.BankerOrderMapper;
import com.ytjj.qmyx.supplychain.mapper.SaleafterOrderUploadJstMapper;
import com.ytjj.qmyx.supplychain.mapper.entity.YxBankerOrder;
import com.ytjj.qmyx.supplychain.mapper.entity.YxReturnGoods;
import com.ytjj.qmyx.supplychain.mapper.entity.YxSaleafterOrderUploadJst;
import com.ytjj.qmyx.supplychain.mapper.entity.YxUploadOrderJst;
import execute.OrderAction;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import request.AfterSaleOrderItemRequest;
import request.AfterSaleOrderRequest;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RefreshScope
public class OrderTimerService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private BankerOrderMapper bankerOrderMapper;
    @Autowired
    private ReturnGoodsService returnGoodsService;
    @Autowired
    private UploadOrderJstService uploadOrderJstService;
    @Resource
    private SaleafterOrderUploadJstMapper saleafterOrderUploadJstMapper;
    @Value("${jushuitan.bankerIds:775,1120}")
    private String jstBankerIdAll;//测试用
    @Value("${jushuitan.sHostUrl:}")
    private String sHostUrl;

    /**
     * 定时更新聚水潭订单信息
     */
    public void queryJuShuiTanOrderInfo(){
        List<String> bankerIds = Arrays.asList(jstBankerIdAll.split(","));
        Example example = new Example(YxBankerOrder.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("bankerId", Arrays.asList(jstBankerIdAll.split(",")));
        criteria.andIn("orderStatus", Arrays.asList(0, 2));
        List<YxBankerOrder> orders = bankerOrderMapper.selectByExample(example);
        log.info("===orders==={}", orders);
        if (CollectionUtils.isEmpty(orders)) {
            return;
        }
//        OrderAction orderAction = new OrderAction(sPartnerId, sPartnerKey, sToken, sHostUrl);

        String redisConstant = RedisConstants.OUT_ERP_KEY;
        bankerIds.stream().forEach(bankerId -> {
            List<YxBankerOrder> signBankerOrders = orders.stream().filter(item -> item.getBankerId().equals(Integer.parseInt(bankerId))).collect(Collectors.toList());
            String partnerId = stringRedisTemplate.opsForValue().get(redisConstant + "partnerId:" + bankerId);
            String partnerKey = stringRedisTemplate.opsForValue().get(redisConstant + "partnerKey:" + bankerId);
            String token = stringRedisTemplate.opsForValue().get(redisConstant + "token:" + bankerId);

            OrderAction orderAction = new OrderAction(partnerId, partnerKey, token, sHostUrl);
            if (signBankerOrders.size() <= 20) {
                String soIds = signBankerOrders.stream().map(s -> s.getOrderNo()).collect(Collectors.joining(","));
                String responseResuleIsStr = null;
                try {
                    responseResuleIsStr = orderAction.queryOrderResultIsStr(soIds, null, null);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (StringUtils.isEmpty(responseResuleIsStr)) {
                    return;
                }
                JSONObject jsonObject = JSONObject.parseObject(responseResuleIsStr);
                OrderResponse response = JSONObject.toJavaObject(jsonObject, OrderResponse.class);

                List<Order> responseOrders = response.orders;
                if (CollectionUtils.isEmpty(responseOrders)) {
                    return;
                }
                responseOrders.stream().forEach(responseOrder -> {
                    String soId = responseOrder.getSo_id();
                    String status = responseOrder.getStatus();
                    if ("Sent".equals(status)) {
                        String l_id = responseOrder.getL_id();//快递单号
                        String lc_id = responseOrder.getLc_id();//物流公司编码

                        Example example1 = new Example(YxBankerOrder.class);
                        example1.createCriteria().andEqualTo("orderNo", soId).andIn("orderStatus", Arrays.asList(0, 2));
                        YxBankerOrder waitUpdateOrder = bankerOrderMapper.selectOneByExample(example1);
                        if (null == waitUpdateOrder) {
                            return;
                        }
                        waitUpdateOrder.setOrderStatus((byte)1);
                        waitUpdateOrder.setExpressNo(l_id);
                        waitUpdateOrder.setExpressCode(parseExpressCode(lc_id));
                        waitUpdateOrder.setExpressRecord("");
                        waitUpdateOrder.setStatus((byte)3);
                        bankerOrderMapper.updateByPrimaryKeySelective(waitUpdateOrder);
                    }else if ("Question".equals(status)) {
                        Example example1 = new Example(YxBankerOrder.class);
                        example1.createCriteria().andEqualTo("orderNo", soId).andIn("orderStatus", Arrays.asList(0, 2));
                        YxBankerOrder waitUpdateOrder = bankerOrderMapper.selectOneByExample(example1);
                        if (null == waitUpdateOrder) {
                            return;
                        }
                        waitUpdateOrder.setStatus((byte)2);
                        bankerOrderMapper.updateByPrimaryKeySelective(waitUpdateOrder);
                    }
                });
            }else {
                for (int i = 0; i < signBankerOrders.size() / 20 + 1; i++) {
                    String soIds = signBankerOrders.subList(i * 20, signBankerOrders.size()
                            < (i * 20 + 20) ? signBankerOrders.size() : (i * 20 + 20))
                            .stream().map(s -> s.getOrderNo())
                            .collect(Collectors.joining(","));
                    String responseResuleIsStr = null;
                    try {
                        responseResuleIsStr = orderAction.queryOrderResultIsStr(soIds, null, null);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    if (StringUtils.isEmpty(responseResuleIsStr)) {
                        return;
                    }
//                    parseResultAndUpdateBankerOrder(responseResuleIsStr);
                    JSONObject jsonObject = JSONObject.parseObject(responseResuleIsStr);
                    OrderResponse response = JSONObject.toJavaObject(jsonObject, OrderResponse.class);

                    List<Order> responseOrders = response.orders;
                    if (CollectionUtils.isEmpty(responseOrders)) {
                        return;
                    }
                    responseOrders.stream().forEach(responseOrder -> {
                        String soId = responseOrder.getSo_id();
                        String status = responseOrder.getStatus();
                        if ("Sent".equals(status)) {
                            String l_id = responseOrder.getL_id();//快递单号
                            String lc_id = responseOrder.getLc_id();//物流公司编码

                            Example example1 = new Example(YxBankerOrder.class);
                            example1.createCriteria().andEqualTo("orderNo", soId).andIn("orderStatus", Arrays.asList(0, 2));
                            YxBankerOrder waitUpdateOrder = bankerOrderMapper.selectOneByExample(example1);
                            if (null != waitUpdateOrder) {
                                waitUpdateOrder.setOrderStatus((byte)1);
                                waitUpdateOrder.setExpressNo(l_id);
                                waitUpdateOrder.setExpressCode(parseExpressCode(lc_id));
                                waitUpdateOrder.setExpressRecord("");
                                waitUpdateOrder.setStatus((byte)3);
                                bankerOrderMapper.updateByPrimaryKeySelective(waitUpdateOrder);
                            }

                        }else if ("Question".equals(status)) {
                            Example example1 = new Example(YxBankerOrder.class);
                            example1.createCriteria().andEqualTo("orderNo", soId).andIn("orderStatus", Arrays.asList(0, 2));
                            YxBankerOrder waitUpdateOrder = bankerOrderMapper.selectOneByExample(example1);
                            if (null != waitUpdateOrder) {
                                waitUpdateOrder.setStatus((byte)2);
                                bankerOrderMapper.updateByPrimaryKeySelective(waitUpdateOrder);
                            }
                        }
                    });
                }
            }
        });
    }

    /**
     * 定时向聚水潭推送售后订单信息
     */
    public void afterSaleOrderToJuShuitan() {
        if (StringUtils.isEmpty(jstBankerIdAll)) {
            return;
        }
        List<String> bankerIds = Arrays.asList(jstBankerIdAll.split(","));
        if (CollectionUtils.isEmpty(bankerIds)) {
            return;
        }
        List<Integer> codesInteger = bankerIds.stream().map(Integer::parseInt).collect(Collectors.toList());
        List<YxReturnGoods> returnGoodsList = returnGoodsService.selectList(codesInteger);
        if (CollectionUtils.isEmpty(returnGoodsList)) {
            return;
        }
        Example example = new Example(YxBankerOrder.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("orderNo", returnGoodsList.stream().map(s -> "QMYX" + s.getOrdersInfoId()).collect(Collectors.toList())).andIn("bankerId", codesInteger);
        List<YxBankerOrder> orders = bankerOrderMapper.selectByExample(example);

        String redisConstant = RedisConstants.OUT_ERP_KEY;
        bankerIds.stream().forEach(bankerId -> {
            List<YxReturnGoods> signBankerOrders = returnGoodsList.stream().filter(item -> item.getBankerId().equals(Integer.parseInt(bankerId))).collect(Collectors.toList());
            String partnerId = stringRedisTemplate.opsForValue().get(redisConstant + "partnerId:" + bankerId);
            String partnerKey = stringRedisTemplate.opsForValue().get(redisConstant + "partnerKey:" + bankerId);
            String token = stringRedisTemplate.opsForValue().get(redisConstant + "token:" + bankerId);
            String singleShopId = stringRedisTemplate.opsForValue().get(redisConstant + "shopId:" + bankerId);

            OrderAction orderAction = new OrderAction(partnerId, partnerKey, token, sHostUrl);
            List<AfterSaleOrderRequest> requestList = new LinkedList<>();
            signBankerOrders.stream().forEach(s -> {
                AfterSaleOrderRequest request = new AfterSaleOrderRequest();
                request.setShop_id(Integer.parseInt(singleShopId));
                request.setOuter_as_id(s.getServiceNo());
                request.setSo_id("QMYX" + s.getOrdersInfoId());
                request.setType("普通退货");
                request.setLogistics_company(ExpressEnum.getExpressName(s.getReturnExpressCompany()));
                request.setL_id(s.getReturnExpressNo());
                switch (s.getStatus()) {
                    case 2:
                        request.setShop_status(JushuitanAfterSaleShopStatusEnum.WAIT_BUYER_RETURN_GOODS.getCode());
                        break;
                    case 3:
                        request.setShop_status(JushuitanAfterSaleShopStatusEnum.WAIT_SELLER_CONFIRM_GOODS.getCode());
                        break;
                    case 4:
                        request.setShop_status(JushuitanAfterSaleShopStatusEnum.WAIT_SELLER_CONFIRM_GOODS.getCode());
                        break;
                    case 5:
                        request.setShop_status(JushuitanAfterSaleShopStatusEnum.SELLER_REFUSE_BUYER.getCode());
                        break;
                    case 6:
                        request.setShop_status(JushuitanAfterSaleShopStatusEnum.CLOSED.getCode());
                        break;
                    case 7:
                        request.setShop_status(JushuitanAfterSaleShopStatusEnum.CLOSED.getCode());//todo 这里待确认给什么值
                        break;
                    case 8:
                        request.setShop_status(JushuitanAfterSaleShopStatusEnum.WAIT_SELLER_CONFIRM_GOODS.getCode());
                        break;
                    case 9:
                        request.setShop_status(JushuitanAfterSaleShopStatusEnum.SUCCESS.getCode());

                }

                List<YxBankerOrder> matchBankerOrder = orders.stream().filter(item -> item.getOrderNo().equals(request.getSo_id())).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(matchBankerOrder)) {
                    return;
                }
                YxBankerOrder bankerOrder = matchBankerOrder.get(0);
                request.setRemark(s.getUserRemarks());
                request.setGood_status("BUYER_RETURNED_GOODS");//买家已退货
                request.setQuestion_type(s.getReturnReason());
                request.setTotal_amount(bankerOrder.getProductPrice());
                request.setRefund(bankerOrder.getProductPrice());
                request.setPayment(BigDecimal.ZERO);

                AfterSaleOrderItemRequest itemRequest = new AfterSaleOrderItemRequest();
                itemRequest.setSku_id(bankerOrder.getThreeSkuId());//可以从yx_banker_order表查询three_sku_id
                itemRequest.setQty(1);
                itemRequest.setAmount(bankerOrder.getProductPrice());
                itemRequest.setType("退货");

                List<AfterSaleOrderItemRequest> items = new ArrayList();
                items.add(itemRequest);
                request.setItems(items);

                requestList.add(request);
            });
            try {
                String response = orderAction.AfterSaleOrderUploadResultIsStr(requestList);
                JSONObject jsonObject = JSONObject.parseObject(response);
                AfterSaleOrderResponse dto = JSONObject.toJavaObject(jsonObject, AfterSaleOrderResponse.class);
                log.info("===向聚水潭推送售后订单信息:{}" + response);
                if (dto.code != 0) {
                    log.info("===向聚水潭推送售后订单失败, 返回参数:{}" + response);
                    String rspMsg = "code=" + dto.code + ", msg=" + dto.msg;
                    return;
                }
                log.info("===向聚水潭推送售后订单成功===");
                try {
                    saveSaleAfterOrderByJST(requestList);
                }catch (Exception e) {
                    log.error("保存售后订单发送记录失败{}", e);
                }
            } catch (Exception e) {
                log.error("===向聚水潭推送售后订单异常,{}", e);
            }
        });
    }

    /**
     * 保存售后订单发送记录
     * @param requestList
     */
    private void saveSaleAfterOrderByJST(List<AfterSaleOrderRequest> requestList) {
        requestList.stream().forEach(item -> {
            YxSaleafterOrderUploadJst jstRecord = YxSaleafterOrderUploadJst.builder()
                    .serviceNo(item.getOuter_as_id())
                    .status(1)
                    .createTime(new Date())
                    .build();
            saleafterOrderUploadJstMapper.insert(jstRecord);
        });
    }

    /**
     * 定时向聚水潭推送失败订单信息开始
     */
    public void uploadOrderToJuShuiTan() {
        Example example = new Example(YxUploadOrderJst.class);
        example.createCriteria().andEqualTo("status", 0);
        List<YxUploadOrderJst> list = uploadOrderJstService.selectByExample(example);

        List<YxBankerOrder> waitUploadOrders = new ArrayList<>();
        list.stream().forEach(jst -> {
            Example example1 = new Example(YxBankerOrder.class);
            example1.createCriteria().andEqualTo("orderNo", jst.getOrderNo());
            YxBankerOrder yxBankerOrder = bankerOrderMapper.selectOneByExample(example1);

//            YxOrdersInfo ordersInfo = orderInfoDao.selectOrderInfoById(Integer.parseInt(yxBankerOrder.getOrderNo().substring(4, yxBankerOrder.getOrderNo().length())));
//            YxOrders orders = ordersDao.selectByPrimaryKey(ordersInfo.getOrderId());
            waitUploadOrders.add(yxBankerOrder);

            String[] jstBankerIds = jstBankerIdAll.split(",");
            if (!Arrays.asList(jstBankerIds).contains(yxBankerOrder.getBankerId())) {
                log.info("===不需要发送聚水潭===", yxBankerOrder.getOrderNo());
                return;
            }

            try {
                log.info("===发送聚水潭开始==={}", yxBankerOrder.getOrderNo());
                String redisConstant = RedisConstants.OUT_ERP_KEY;
                String signShopId = stringRedisTemplate.opsForValue().get(redisConstant + "shopId:" + yxBankerOrder.getBankerId());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                request.OrderUploadRequest uploadRequest = new request.OrderUploadRequest();
                uploadRequest.setShop_id(Integer.parseInt(signShopId));
                uploadRequest.setSo_id(yxBankerOrder.getOrderNo());
                uploadRequest.setOrder_date(sdf.format(yxBankerOrder.getCreateTime()));
                uploadRequest.setShop_status(JushuitanOrderStatusEnum.WAIT_SELLER_SEND_GOODS.getCode());
                uploadRequest.setShop_buyer_id(yxBankerOrder.getUserTel());
                uploadRequest.setReceiver_state(yxBankerOrder.getProvince());
                uploadRequest.setReceiver_city(yxBankerOrder.getCity());
                uploadRequest.setReceiver_district(yxBankerOrder.getArea());
                uploadRequest.setReceiver_address(yxBankerOrder.getDeliveryAddress());
                uploadRequest.setReceiver_name(yxBankerOrder.getUserName());
                uploadRequest.setReceiver_phone(yxBankerOrder.getUserTel());
                uploadRequest.setReceiver_mobile(yxBankerOrder.getUserTel());
                uploadRequest.setPay_amount(yxBankerOrder.getProductPrice());
                uploadRequest.setFreight(BigDecimal.ZERO);
                uploadRequest.setShop_modified(sdf.format(yxBankerOrder.getCreateTime()));

                List<request.OrderUploadRequest> sendJSTList = new ArrayList<>();
                sendJSTList.add(uploadRequest);
                sendJushuitan(String.valueOf(yxBankerOrder.getBankerId()), sendJSTList);
            } catch (Exception e) {
                log.error("===发送聚水潭失败==={}", e);
            }
        });

    }

    private void sendJushuitan(String bankerId, List<request.OrderUploadRequest> requestsNew) {
        if (CollectionUtils.isEmpty(requestsNew)) {
            return;
        }
        try {
            String redisConstant = RedisConstants.OUT_ERP_KEY;
            String partnerId = stringRedisTemplate.opsForValue().get(redisConstant + "partnerId:" + bankerId);
            String partnerKey = stringRedisTemplate.opsForValue().get(redisConstant + "partnerKey:" + bankerId);
            String token = stringRedisTemplate.opsForValue().get(redisConstant + "token:" + bankerId);
            OrderAction orderAction = new OrderAction(partnerId, partnerKey, token, sHostUrl);
            String result = orderAction.orderUploadResultIsStr(requestsNew);
            log.info("===jushuitan result==={}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            JunshuitanRsponseDto dto = JSONObject.toJavaObject(jsonObject, JunshuitanRsponseDto.class);
            log.info("===订单发送聚水潭响应信息:{}", result);
            if (dto.getCode() != 0) {
                log.info("===订单发送聚水潭失败, 返回参数:{}", dto);
                String rspMsg = "code=" + dto.getCode() + ", msg=" + dto.getMsg();
                return;
            }
            uploadOrderJstService.updateStatusByOrderNo(requestsNew.get(0).getSo_id(), 1);
            log.info("===订单发送聚水潭成功===");
        } catch (Exception e) {
            log.error("===订单发送聚水潭接口异常,{}", e);
        }
    }

    private String parseExpressCode(String lc_id) {
        if (StringUtils.isEmpty(lc_id)) {
            return "";
        }
        switch (lc_id) {
            case "SF":
                return "shunfeng";
            case "DBL" :
                return "debangwuliu";
            case "GTO" :
                return "yuantong";
            case "TTKDEX":
                return "tiantian";
            case "FEDEX":
                return "lianbangkuaidi";
            case "QFKD":
                return "quanfengkuaidi";
            case "CNEX":
                return "jiajiwuliu";
            case "GDEMS":
                return "GDEMS";//广东EMS
            case "UAPEX":
                return "quanyikuaidi";
            case "HOAU":
                return "tiandihuayu";
            case "DUMMY":
                return "DUMMY";//无需物流
            case "BJCS":
                return "BJCS";//城市100
            case "LB":
                return "longbanwuliu";
            case "QRT":
                return "zengyisudi";
            case "GZFY":
                return "GZFY";//凡宇速递
            case "KXTX":
                return "KXTX";//卡行天下
            case "FKDWL":
                return "FKDWL";//飞康达物流
            case "QRTKD":
                return "QRTKD";//全日通快递
            case "CCES":
                return "CCES";//CCES快递
            case "SYHY":
                return "SYHY";//苏粤货运
            case "GPWL":
                return "GPWL";//贵平物流
            case "JYWL":
                return "jiayiwuliu";
            case "GZND":
                return "GZND";//港中能da
            case "CSZX":
                return "CSZX";//城市之星
            case "XSDTC":
                return "XSDTC";//新时代通城
            case "GSDWL":
                return "GSDWL";//共速达物流
            case "DTLY":
                return "DTLY";//大田陆运
            case "DHL Global Mail":
                return "DHL Global Mail";//DHL Global Mail
            case "YUNDA":
                return "yunda";
            case "STO":
                return "shentong";
            case "YTO":
                return "yuantong";
            case "ZTO":
                return "zhongtong";
            case "ZTO.1":
                return "zhongtong";
            case "ZTO.2":
                return "zhongtong";
            case "ZTO.3":
                return "zhongtong";
            case "ZTO.4":
                return "zhongtong";
            case "ZTO.5":
                return "zhongtong";
            case "ZTO.6":
                return "zhongtong";
            case "ZTO.7":
                return "zhongtong";
            case "ZTO.8":
                return "zhongtong";
            case "ZTO.9":
                return "zhongtong";
            case "DBKD":
                return "debangwuliu";
            case "YTO.1":
                return "yuantong";
            case "YTO.2":
                return "yuantong";
            case "YTO.3":
                return "yuantong";
            case "YTO.4":
                return "yuantong";
            case "YTO.5":
                return "yuantong";
            case "YTO.6":
                return "yuantong";
            case "YTO.7":
                return "yuantong";
            case "YTO.8":
                return "yuantong";
            case "YTO.9":
                return "yuantong";
            case "3108002701_1011":
                return "zhongtong";
            case "CP570969":
                return "danniao";
            case "CPAM":
                return "youzhengguonei";
            case "DISTRIBUTOR_1710055":
                return "youzhengbk";
            case "EMS":
                return "ems";
            case "EMS.ECLP":
                return "ems";
            case "express":
                return "zhongyouex";
            case "EYB":
                return "emsbg";
            case "HTKY":
                return "huitongkuaidi";
            case "HTKY.ECLP":
                return "huitongkuaidi";
            case "JTSD":
                return "jtexpress";
            case "PINGJUN":
                return "pjbest";
            case "POSTB":
                return "youzhengguonei";
            case "SNSCDB001":
                return "suning";
            case "SNWL":
                return "suning";
            case "STO.ECLP":
                return "shentong";
            case "STO-SPEEDA":
                return "shentong";
            case "YUNDA.ECLP":
                return "yunda";
            case "YUNDAWL":
                return "yundakuaiyun";
            case "ZJS":
                return "zhaijisong";
            case "ZMKM":
                return "zhimakaimen";
            case "ZTO.ECLP":
                return "zhongtong";
            case "ZYKD":
                return "zhongyouex";
        }
        return lc_id;
    }
}
